package com.gitee.l0km.aocache.example.pcw.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import com.gitee.l0km.aocache.config.CacheConfigSupplier;

import static com.gitee.l0km.aocache.MemberCache.INSTANCE;

/**
 * 
 * 方法缓存切面定义<br>
 * @author guyadong
 *
 */
@Aspect
public class AocachePcwAspect {

	@Around("rangeTypeUtils() || rangeDateSupport() || rangeCaseSupport() || rangeTypeNameUtils() "
			+ "|| range() ")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint,CacheConfigSupplier.DEFAULT_SUPPLIER);
    }
	
	@Around("aoCacheable() && rangeAnn()")
    public Object around0(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint);
    }
	@Around("genericsCtor() || testUserCtor()")
	public Object aroundCtor(ProceedingJoinPoint joinPoint) throws Throwable {
		return INSTANCE.around(joinPoint);
	}
	/**
	 * 定义切入点为com.gitee.l0km.aocache.example.ltw.AocachePcw*Test类的任意方法执行
	 */
	@Pointcut("execution(* com.gitee.l0km.aocache.example.pcw.AocachePcw*Test.*(..))")
	public void rangeAnn() {
	}
    /**
     * 定义切入点为com.gitee.l0km.aocache.example.ltw.AocachePcwTest.parseDateString方法执行
     */
    @Pointcut("execution(* com.gitee.l0km.aocache.example.pcw.AocachePcwTest.parseDateString(..))")
    public void range() {
    }
    /**
     * 定义切入点为有{@link com.gitee.l0km.aocache.annotations.AoCacheable}注解的所有函数
     */
    @Pointcut("@annotation(com.gitee.l0km.aocache.annotations.AoCacheable)")
    public void aoCacheable() {
    }
    /**
     * 定义切入点为类名为DateSupport类的所有静态方法执行
     */
    @Pointcut("call(java.util.Date *..DateSupport.*(..))")
    public void rangeDateSupport() {
    }
    /**
     * 定义切入点为类名为TypeNameUtils.getTypeName方法执行
     */
    @Pointcut("call(String *..TypeNameUtils.getTypeName(..))")
    public void rangeTypeNameUtils() {
    }
    /**
     * 定义切入点为net.gdface.utils.CaseSupport.toCamelcase方法执行
     */
    @Pointcut("call(String net.gdface.utils.CaseSupport.toCamelcase(..))")
    public void rangeCaseSupport() {
    }
    /**
     * 定义切入点为net.gdface.utils.TypeUtils.listToken方法执行
     */
    @Pointcut("call(com.google.common.reflect.TypeToken net.gdface.utils.TypeUtils.listToken(..))")
    public void rangeTypeUtils() {
    }
    /**
     * 定义切入点为 {@link com.gitee.l0km.aocache.example.pcw.AocachePcwAnnotTest.TestUser}构造方法执行(private除外)<br>
     * aspectJ不能拦截私有构造方法<br>
     * 参见 <a ref="https://stackoverflow.com/questions/63187952/aspectj-intercept-constructor-when-method-reference-is-used">《AspectJ: intercept constructor when method reference is used》</a>
     */
    @Pointcut("call(com.gitee.l0km.aocache.example.pcw.AocachePcwTest.TestUser.new(..))")
    public void testUserCtor() {
    }
    /**
     * 定义切入点为 net.gdface.reflection.generics 包下所有类的构造方法
     */
    @Pointcut("call(net.gdface.reflection.generics.*.new(..))")
    public void genericsCtor() {
    }
    public static AocachePcwAspect aspectOf() {
    	return new AocachePcwAspect();
    }
}
